package grpc_proxy_middleware

import (
	"encoding/json"
	"fmt"
	"gitee.com/zhoulvvv/my_go_gateway/dao"
	"gitee.com/zhoulvvv/my_go_gateway/public"
	"github.com/pkg/errors"
	"google.golang.org/grpc"
	"google.golang.org/grpc/metadata"
	"log"
)

// GRPC 租户流量统计
func GRPCJwtFlowCountModeMiddleware(service *dao.ServiceDetail) func(srv interface{}, ss grpc.ServerStream,
	info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
	return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
		md, ok := metadata.FromIncomingContext(ss.Context())
		if !ok {
			log.Printf("【GRPC 租户流量统计】 failed with error metadata.FromIncomingContext(ss.Context())")
		}
		// 获取租户信息
		apps := md.Get("app")
		// apps := metadata.ValueFromIncomingContext(ss.Context(), "app")
		if len(apps) == 0 {
			if err := handler(srv, ss); err != nil {
				log.Printf("【GRPC】RPC failed with error %v\n", err)
			}
			return nil
		}
		app := &dao.App{}
		if err := json.Unmarshal([]byte(apps[0]), app); err != nil {
			log.Printf("【GRPC 租户流量统计】 json.Unmarshal([]byte(apps[0]),app) %v\n", err)
		}
		// 统计项： 1 全站 2 服务 3 租户
		// 租户统计器
		appCounter, err := public.FlowCounterHandler.GetCounter(public.FlowAppPrefix + app.AppId)
		if err != nil {
			return errors.New("【GRPC】获取服务统计器失败：" + err.Error())
		}
		appCounter.Increase()
		log.Printf("【GRPC】租户统计 qps:%v dayCount:%v", appCounter.QPS, appCounter.TotalCount)
		// 判断租户的日请求量是否超标
		if app.Qpd > 0 && appCounter.TotalCount > int64(app.Qpd) {
			return errors.New(fmt.Sprintf("【GRPC】该接口当天请求已经达到限流，限流数量：%v，已经请求的数量：%v",
				app.Qpd, appCounter.TotalCount))
		}
		if err := handler(srv, ss); err != nil {
			log.Printf("【GRPC】RPC failed with error %v\n", err)
		}
		return nil
	}
}
